package pl.elka.pszt.model;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import pl.elka.pszt.model.argument.Argument;
import pl.elka.pszt.model.argument.Constant;
import pl.elka.pszt.model.argument.Variable;
import pl.elka.pszt.model.literal.Literal;

/**
 * Przypisanie argumentow do literalu.
 * 
 * @author Andrzej Makarewicz
 * 
 */
public class Assigned {
	
	final Literal literal;
	final List<Argument> arguments;
	
	public Assigned(Literal literal, Map<Variable, Constant> assigment) {
		this.literal = literal;
		
		List<Argument> args = literal.getArguments();
		arguments = new ArrayList<Argument>(args.size());
		for (Argument arg : args) {
			arguments.add(arg.isVariable() ? assigment.get(arg) : arg);
		}
	}
	
	/**
	 * Zamienia bezposrednio fakt w przypisany liteal - potrzebne do uzyskania
	 * dobrego hasha
	 * 
	 * @param fact
	 */
	public Assigned(Fact fact) {
		this.literal = fact.getConclusion();
		this.arguments = fact.getConclusion().getArguments();
	}
	
	/**
	 * 
	 * @return przypisany liteal
	 */
	public Literal getLiteral() {
		return literal;
	}
	
	/**
	 * 
	 * @return argumenty przypisane do literalu
	 */
	public List<Argument> getArguments() {
		return arguments;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((arguments == null) ? 0 : arguments.hashCode());
		result = prime * result + ((literal == null) ? 0 : literal.hashCodeSimplified());
		return result;
	}
	
	@Override
	public boolean equals(Object obj) {
		if (this == obj) return true;
		if (obj == null) return false;
		if (getClass() != obj.getClass()) return false;
		Assigned other = (Assigned) obj;
		if (literal == null) {
			if (other.literal != null) return false;
		} else if (!literal.equalsSimplified(other.literal)) return false;
		if (arguments == null) {
			if (other.arguments != null) return false;
		} else if (!arguments.equals(other.arguments)) return false;
		return true;
	}
	
	@Override
	public String toString() {
		return "Assigned [literal=" + literal + ", arguments=" + arguments + "]";
	}
}
